package org.lds.logger.xml;

import com.thoughtworks.xstream.XStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.lds.logger.config.Configuration;
import org.lds.logger.config.ConfigurationReader;
import org.lds.logger.config.appender.ConsoleAppender;
import org.lds.logger.config.appender.FileAppender;
import org.lds.logger.config.appender.RollingFileAppender;
import org.lds.logger.config.filter.AbstractAppenderFilter;
import org.lds.logger.config.filter.AbstractGlobalFilter;
import org.lds.logger.config.layout.PatternLayout;
import org.lds.logger.util.Utils;

import java.io.File;
import java.net.URL;
import java.nio.charset.Charset;

public class ConfigurationXMLReader implements ConfigurationReader {
    private XStream configurationXStream;

    public ConfigurationXMLReader() {
        init();
    }

    private void init() {
        configurationXStream = new XStream();
        configurationXStream.allowTypes(new Class[]{
                XMLConfiguration.class, XMLProperty.class, XMLAppender.class, XMLLogger.class, XMLRoot.class,
                XMLFilter.class, XMLLayout.class, XMLAppenderReference.class,
                ConsoleAppender.class, FileAppender.class, RollingFileAppender.class,
                AbstractGlobalFilter.class, AbstractAppenderFilter.class,
                PatternLayout.class
        });
        configurationXStream.processAnnotations(XMLConfiguration.class);
        // 开起注解功能
        configurationXStream.autodetectAnnotations(true);
        // 忽律未知字段
        configurationXStream.ignoreUnknownElements();
    }

    @Override
    public Configuration parse() {
        String xml = getResource();
        XMLConfiguration xmlConfiguration = getXMLConfiguration(xml);
        if (xmlConfiguration == null) return null;
        return xmlConfiguration.buildConfiguration();
    }

    private String getResource() {
        try {
            URL url = XMLConfiguration.class.getClassLoader().getResource("logger.xml");
            File file = FileUtils.toFile(url);
            return FileUtils.readFileToString(file, Charset.defaultCharset());
        } catch (Throwable e) {
            Utils.report("logger.xml配置文件读取失败. error=" + e.getMessage());
            return null;
        }
    }

    private XMLConfiguration getXMLConfiguration(String xml) {
        if (StringUtils.isEmpty(xml)) return null;
        try {
            return (XMLConfiguration) configurationXStream.fromXML(xml);
        } catch (Throwable e) {
            Utils.report("logger.xml配置文件解析失败. error=" + e.getMessage());
            return null;
        }
    }

    public String toXML(XMLConfiguration xmlConfiguration) {
        return configurationXStream.toXML(xmlConfiguration);
    }
}
